home *** CD-ROM | disk | FTP | other *** search
/ Visual Cafe 3 / Visual Cafe 3.ISO / Vcafe / JFC.bin / JTextPane.java < prev    next >
Text File  |  1998-06-30  |  15KB  |  421 lines

  1. /*
  2.  * @(#)JTextPane.java    1.59 98/04/09
  3.  * 
  4.  * Copyright (c) 1997 Sun Microsystems, Inc. All Rights Reserved.
  5.  * 
  6.  * This software is the confidential and proprietary information of Sun
  7.  * Microsystems, Inc. ("Confidential Information").  You shall not
  8.  * disclose such Confidential Information and shall use it only in
  9.  * accordance with the terms of the license agreement you entered into
  10.  * with Sun.
  11.  * 
  12.  * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE
  13.  * SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
  14.  * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
  15.  * PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR ANY DAMAGES
  16.  * SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING
  17.  * THIS SOFTWARE OR ITS DERIVATIVES.
  18.  * 
  19.  */
  20. package com.sun.java.swing;
  21.  
  22. import java.awt.*;
  23. import java.awt.event.ActionEvent;
  24. import java.io.Serializable;
  25. import com.sun.java.swing.text.*;
  26. import com.sun.java.swing.event.*;
  27. import com.sun.java.swing.plaf.*;
  28.  
  29. /**
  30.  * A text component that can be marked up with attributes that are
  31.  * represented graphically.  This component models paragraphs
  32.  * that are composed of runs of character level attributes.  Each
  33.  * paragraph may have a logical style attached to it which contains
  34.  * the default attributes to use if no overriden by attributes set
  35.  * on the paragraph or character run.  Components and images may
  36.  * be embedded in the flow of text.
  37.  * <p>
  38.  * For the keyboard keys used by this component in the standard Look and
  39.  * Feel (L&F) renditions, see the
  40.  * <a href="doc-files/Key-Index.html#JTextPane">JTextPane</a> key assignments.
  41.  * <p>
  42.  * Warning: serialized objects of this class will not be compatible with
  43.  * future swing releases.  The current serialization support is appropriate
  44.  * for short term storage or RMI between Swing1.0 applications.  It will
  45.  * not be possible to load serialized Swing1.0 objects with future releases
  46.  * of Swing.  The JDK1.2 release of Swing will be the compatibility
  47.  * baseline for the serialized form of Swing objects.
  48.  *
  49.  * @author  Timothy Prinzing
  50.  * @version 1.59 04/09/98
  51.  * @see StyledEditorKit
  52.  */
  53. public class JTextPane extends JEditorPane {
  54.  
  55.     /**
  56.      * Constructs a new JTextPane.  A new instance of StyledEditorKit is
  57.      * created and set, and the document model set to null.
  58.      */
  59.     public JTextPane() {
  60.         super();
  61.         setEditorKit(new StyledEditorKit());
  62.     }
  63.  
  64.     /**
  65.      * Constructs a new JTextPane, with a specified document model.
  66.      * A new instance of StyledEditorKit is created and set.
  67.      *
  68.      * @param doc the document model
  69.      */
  70.     public JTextPane(StyledDocument doc) {
  71.         this();
  72.         setStyledDocument(doc);
  73.     }
  74.  
  75.     /**
  76.      * Returns the class ID for the UI.
  77.      *
  78.      * @return the ID ("TextPaneUI")
  79.      * @see JComponent#getUIClassID
  80.      * @see UIDefaults#getUI
  81.      */
  82.     public String getUIClassID() {
  83.         return "TextPaneUI";
  84.     }
  85.  
  86.     /**
  87.      * Associates the editor with a text document.  This
  88.      * must be a StyledDocument.
  89.      *
  90.      * @param doc  the document to display/edit
  91.      * @exception IllegalArgumentException  if doc can't
  92.      *   be narrowed to a StyledDocument which is the
  93.      *   required type of model for this text component
  94.      */
  95.     public void setDocument(Document doc) {
  96.         if (doc instanceof StyledDocument) {
  97.             super.setDocument(doc);
  98.         } else {
  99.             throw new IllegalArgumentException("Model must be StyledDocument");
  100.         }
  101.     }
  102.  
  103.     /**
  104.      * Associates the editor with a text document.
  105.      * The currently registered factory is used to build a view for
  106.      * the document, which gets displayed by the editor.
  107.      *
  108.      * @param doc  the document to display/edit
  109.      */
  110.     public void setStyledDocument(StyledDocument doc) {
  111.         super.setDocument(doc);
  112.     }
  113.  
  114.     /**
  115.      * Fetches the model associated with the editor.  
  116.      *
  117.      * @return the model
  118.      */
  119.     public StyledDocument getStyledDocument() {
  120.         return (StyledDocument) getDocument();
  121.     } 
  122.  
  123.     /**
  124.      * Replaces the currently selected content with new content
  125.      * represented by the given string.  If there is no selection
  126.      * this amounts to an insert of the given text.  If there
  127.      * is no replacement text this amounts to a removal of the
  128.      * current selection.  The replacement text will have the
  129.      * attributes currently defined for input.  If the document is not
  130.      * editable, beep and return.  Then if the document is null, do nothing.
  131.      * If the content to insert is null or empty, ignore it.
  132.      * <p>
  133.      * This method is thread safe, although most Swing methods
  134.      * are not. Please see 
  135.      * <A HREF="http://java.sun.com/products/jfc/swingdoc-archive/threads.html">Threads
  136.      * and Swing</A> for more information.     
  137.      *
  138.      * @param content  the content to replace the selection with
  139.      */
  140.     public void replaceSelection(String content) {
  141.         if (! isEditable()) {
  142.             getToolkit().beep();
  143.             return;
  144.         }
  145.         Document doc = getStyledDocument();
  146.         if (doc != null) {
  147.             try {
  148.                 Caret caret = getCaret();
  149.                 int p0 = Math.min(caret.getDot(), caret.getMark());
  150.                 int p1 = Math.max(caret.getDot(), caret.getMark());
  151.                 if (p0 != p1) {
  152.                     doc.remove(p0, p1 - p0);
  153.                 }
  154.                 if (content != null && content.length() > 0) {
  155.                     doc.insertString(p0, content, getInputAttributes());
  156.                 }
  157.             } catch (BadLocationException e) {
  158.                 getToolkit().beep();
  159.             }
  160.         }
  161.     }
  162.  
  163.     /**
  164.      * Inserts a component into the document as a replacement
  165.      * for the currently selected content.  If there is no
  166.      * selection the component is effectively inserted at the 
  167.      * current position of the caret.  This is represented in
  168.      * the associated document as an attribute of one character 
  169.      * of content.  
  170.      *
  171.      * @param c    the component to insert
  172.      */
  173.     public void insertComponent(Component c) {
  174.         MutableAttributeSet inputAttributes = getInputAttributes();
  175.         inputAttributes.removeAttributes(inputAttributes);
  176.         StyleConstants.setComponent(inputAttributes, c);
  177.         replaceSelection(" ");
  178.         inputAttributes.removeAttributes(inputAttributes);
  179.     }
  180.  
  181.     /**
  182.      * Inserts an icon into the document as a replacement
  183.      * for the currently selected content.  If there is no
  184.      * selection the icon is effectively inserted at the 
  185.      * current position of the caret.  This is represented in
  186.      * the associated document as an attribute of one character 
  187.      * of content.  
  188.      * <p>
  189.      * This method is thread safe, although most Swing methods
  190.      * are not. Please see 
  191.      * <A HREF="http://java.sun.com/products/jfc/swingdoc-archive/threads.html">Threads
  192.      * and Swing</A> for more information.     
  193.      *
  194.      * @param g    the icon to insert
  195.      * @see Icon
  196.      */
  197.     public void insertIcon(Icon g) {
  198.         MutableAttributeSet inputAttributes = getInputAttributes();
  199.         inputAttributes.removeAttributes(inputAttributes);
  200.         StyleConstants.setIcon(inputAttributes, g);
  201.         replaceSelection(" ");
  202.         inputAttributes.removeAttributes(inputAttributes);
  203.     }
  204.  
  205.     /**
  206.      * Adds a new style into the logical style hierarchy.  Style attributes
  207.      * resolve from bottom up so an attribute specified in a child
  208.      * will override an attribute specified in the parent.
  209.      *
  210.      * @param nm   the name of the style (must be unique within the
  211.      *   collection of named styles).  The name may be null if the style 
  212.      *   is unnamed, but the caller is responsible
  213.      *   for managing the reference returned as an unnamed style can't
  214.      *   be fetched by name.  An unnamed style may be useful for things
  215.      *   like character attribute overrides such as found in a style 
  216.      *   run.
  217.      * @param parent the parent style.  This may be null if unspecified
  218.      *   attributes need not be resolved in some other style.
  219.      * @return the new Style 
  220.      */
  221.     public Style addStyle(String nm, Style parent) {
  222.         StyledDocument doc = getStyledDocument();
  223.         return doc.addStyle(nm, parent);
  224.     }
  225.  
  226.     /**
  227.      * Removes a named non-null style previously added to the document.  
  228.      *
  229.      * @param nm  the name of the style to remove
  230.      */
  231.     public void removeStyle(String nm) {
  232.         StyledDocument doc = getStyledDocument();
  233.         doc.removeStyle(nm);
  234.     }
  235.  
  236.     /**
  237.      * Fetches a named non-null style previously added.
  238.      *
  239.      * @param nm  the name of the style
  240.      * @return the style
  241.      */
  242.     public Style getStyle(String nm) {
  243.         StyledDocument doc = getStyledDocument();
  244.         return doc.getStyle(nm);
  245.     }
  246.  
  247.     /**
  248.      * Sets the logical style to use for the paragraph at the
  249.      * current caret position.  If attributes aren't explicitly set 
  250.      * for character and paragraph attributes they will resolve 
  251.      * through the logical style assigned to the paragraph, which
  252.      * in term may resolve through some hierarchy completely 
  253.      * independant of the element hierarchy in the document.
  254.      * <p>
  255.      * This method is thread safe, although most Swing methods
  256.      * are not. Please see 
  257.      * <A HREF="http://java.sun.com/products/jfc/swingdoc-archive/threads.html">Threads
  258.      * and Swing</A> for more information.     
  259.      *
  260.      * @param s  the logical style to assign to the paragraph, or null for
  261.      *  no style
  262.      */
  263.     public void setLogicalStyle(Style s) {
  264.         StyledDocument doc = getStyledDocument();
  265.         doc.setLogicalStyle(getCaretPosition(), s);
  266.     }
  267.  
  268.     /** 
  269.      * Fetches the logical style assigned to the paragraph 
  270.      * represented by the current position of the caret, or null.
  271.      *
  272.      * @return the style
  273.      */
  274.     public Style getLogicalStyle() {
  275.         StyledDocument doc = getStyledDocument();
  276.         return doc.getLogicalStyle(getCaretPosition());
  277.     }
  278.  
  279.     /**
  280.      * Fetches the character attributes in effect at the 
  281.      * current location of the caret, or null.  
  282.      *
  283.      * @return the attributes, or null
  284.      */
  285.     public AttributeSet getCharacterAttributes() {
  286.         StyledDocument doc = getStyledDocument();
  287.         Element run = doc.getCharacterElement(getCaretPosition());
  288.         if (run != null) {
  289.             return run.getAttributes();
  290.         }
  291.         return null;
  292.     }
  293.  
  294.     /**
  295.      * Applies the given attributes to character 
  296.      * content.  If there is a selection, the attributes
  297.      * are applied to the selection range.  If there
  298.      * is no selection, the attributes are applied to
  299.      * the input attribute set which defines the attributes
  300.      * for any new text that gets inserted.
  301.      * <p>
  302.      * This method is thread safe, although most Swing methods
  303.      * are not. Please see 
  304.      * <A HREF="http://java.sun.com/products/jfc/swingdoc-archive/threads.html">Threads
  305.      * and Swing</A> for more information.     
  306.      *
  307.      * @param attr the attributes
  308.      * @param replace if true, then replace the existing attributes first
  309.      */
  310.     public void setCharacterAttributes(AttributeSet attr, boolean replace) {
  311.         int p0 = getSelectionStart();
  312.         int p1 = getSelectionEnd();
  313.         if (p0 != p1) {
  314.             StyledDocument doc = getStyledDocument();
  315.             doc.setCharacterAttributes(p0, p1 - p0, attr, replace);
  316.         } else {
  317.             MutableAttributeSet inputAttributes = getInputAttributes();
  318.             if (replace) {
  319.                 inputAttributes.removeAttributes(inputAttributes);
  320.             }
  321.             inputAttributes.addAttributes(attr);
  322.         }
  323.     }
  324.  
  325.     /**
  326.      * Fetches the current paragraph attributes in effect
  327.      * at the location of the caret, or null if none.
  328.      *
  329.      * @return the attributes
  330.      */
  331.     public AttributeSet getParagraphAttributes() {
  332.         StyledDocument doc = getStyledDocument();
  333.         Element paragraph = doc.getParagraphElement(getCaretPosition());
  334.         if (paragraph != null) {
  335.             return paragraph.getAttributes();
  336.         }
  337.         return null;
  338.     }
  339.  
  340.     /**
  341.      * Applies the given attributes to paragraphs.  If
  342.      * there is a selection, the attributes are applied
  343.      * to the paragraphs that intersect the selection.
  344.      * if there is no selection, the attributes are applied
  345.      * to the paragraph at the current caret position.
  346.      * <p>
  347.      * This method is thread safe, although most Swing methods
  348.      * are not. Please see 
  349.      * <A HREF="http://java.sun.com/products/jfc/swingdoc-archive/threads.html">Threads
  350.      * and Swing</A> for more information.     
  351.      *
  352.      * @param attr the non-null attributes
  353.      * @param replace if true, replace the existing attributes first
  354.      */
  355.     public void setParagraphAttributes(AttributeSet attr, boolean replace) {
  356.         int p0 = getSelectionStart();
  357.         int p1 = getSelectionEnd();
  358.         StyledDocument doc = getStyledDocument();
  359.         doc.setParagraphAttributes(p0, p1 - p0, attr, replace);
  360.     }
  361.  
  362.     /**
  363.      * Gets the input attributes for the pane.
  364.      *
  365.      * @return the attributes
  366.      */
  367.     public MutableAttributeSet getInputAttributes() {
  368.         return getStyledEditorKit().getInputAttributes();
  369.     }
  370.  
  371.     /**
  372.      * Gets the editor kit.
  373.      *
  374.      * @return the editor kit.
  375.      */
  376.     protected final StyledEditorKit getStyledEditorKit() {
  377.         return (StyledEditorKit) getEditorKit();
  378.     }
  379.  
  380.     // --- JEditorPane ------------------------------------
  381.  
  382.     /**
  383.      * Creates the EditorKit to use by default.  This
  384.      * is implemented to return StyledEditorKit.
  385.      *
  386.      * @return the editor kit
  387.      */
  388.     protected EditorKit createDefaultEditorKit() {
  389.         return new StyledEditorKit();
  390.     }
  391.  
  392.     /**
  393.      * Sets the currently installed kit for handling
  394.      * content.  This is the bound property that
  395.      * establishes the content type of the editor.
  396.      * 
  397.      * @param kit the desired editor behavior.
  398.      * @exception IllegalArgumentException if kit is not a StyledEditorKit
  399.      */
  400.     public final void setEditorKit(EditorKit kit) {
  401.         if (kit instanceof StyledEditorKit) {
  402.             super.setEditorKit(kit);
  403.         } else {
  404.             throw new IllegalArgumentException("Must be StyledEditorKit");
  405.         }
  406.     }
  407.  
  408.     // --- Scrollable  ----------------------------------------
  409.  
  410.     /**
  411.      * Returns true if a viewport should always force the width of this 
  412.      * Scrollable to match the width of the viewport.  
  413.      * 
  414.      * @return true if a viewport should force the Scrollables width to match its own.
  415.      */
  416.     public boolean getScrollableTracksViewportWidth() {
  417.         return true;
  418.     }
  419.  
  420. }
  421.